package com.registration.controller;

import com.registration.Annotation.OperateLog;
import com.registration.bean.OrderBean;
import com.registration.bean.PaymentBean;
import com.registration.bean.ScheduleBean;
import com.registration.mapper.ScheduleMapper;
import com.registration.service.OrderService;
import com.registration.service.PaymentService;
import com.registration.service.ScheduleService;
import com.registration.util.JsonResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@CrossOrigin
@RequestMapping("/api/v1/payment")
public class PaymentController {

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private ScheduleMapper scheduleMapper;



    /** 1. 查询就诊人待缴费项目 */
    @GetMapping("/pending/{patientId}")
    @OperateLog("查询就诊人待缴费项目")
    public JsonResponse pending(@PathVariable Integer patientId) {
        JsonResponse resp = new JsonResponse();
        try {
            List<PaymentBean> list = paymentService.selectPendingPaymentItemsByUserId(patientId);
            resp.setCode(0);
            resp.setMsg("查询成功");
            resp.setData(list);
        } catch (Exception e) {
            resp.setCode(1);
            resp.setMsg("查询失败：" + e.getMessage());
            e.printStackTrace();
        }
        return resp;
    }

    /** 2. 查询就诊人缴费记录 */
        @GetMapping("/record/{patientId}")
        @OperateLog("查询就诊人缴费记录")
        public JsonResponse records(@PathVariable Integer patientId) {
            JsonResponse resp = new JsonResponse();
            try {
                List<PaymentBean> list = paymentService.selectPaymentRecordsByUserId(patientId);
                resp.setCode(0);
                resp.setMsg("查询成功");
                resp.setData(list);
            } catch (Exception e) {
                resp.setCode(1);
                resp.setMsg("查询失败：" + e.getMessage());
                e.printStackTrace();
            }
            return resp;
        }

        /** 3. 新增缴费记录  order和payment同时添加*/
        @PostMapping("/create")
        @OperateLog("创建缴费记录")
        @Transactional(rollbackFor = Exception.class)
        public JsonResponse create(@RequestBody PaymentBean paymentBean) {
            JsonResponse jsonResponse = new JsonResponse();
            try {
                System.out.println("接收到支付请求: " + paymentBean);

                // 验证必要参数
                if (paymentBean.getUser_id() == null) {
                    return jsonResponse.fail("用户ID不能为空");
                }
                if (paymentBean.getPatient_id() == null) {
                    return jsonResponse.fail("患者ID不能为空");
                }
                if (paymentBean.getAmount() == null) {
                    return jsonResponse.fail("支付金额不能为空");
                }

                OrderBean order;
                // 如果没有订单ID，则先创建订单
                if (paymentBean.getOrder_id() == null) {
                    // 检查创建订单所需参数
                    if (paymentBean.getDoctor_id() == null || paymentBean.getSchedule_id() == null ||
                            paymentBean.getTime_slot() == null || paymentBean.getVisit_date() == null) {
                        return jsonResponse.fail("创建订单缺少必要参数");
                    }

                    // 构造订单对象
                    OrderBean newOrder = new OrderBean();
                    newOrder.setUser_id(paymentBean.getUser_id());
                    newOrder.setPatient_id(paymentBean.getPatient_id());
                    newOrder.setDoctor_id(paymentBean.getDoctor_id());
                    newOrder.setSchedule_id(paymentBean.getSchedule_id());
                    newOrder.setVisit_date(paymentBean.getVisit_date());
                    newOrder.setTime_slot(paymentBean.getTime_slot());
                    newOrder.setSymptoms(paymentBean.getSymptoms());
                    newOrder.setAmount(paymentBean.getAmount());


                    // 从排班获取科室ID（使用普通查询方法，避免锁定号源）
                    ScheduleBean schedule = scheduleMapper.selectScheduleById(paymentBean.getSchedule_id());
                    if (schedule == null) {
                        return jsonResponse.fail("排班信息不存在");
                    }
                    newOrder.setDept_id(schedule.getDept_id());
                    newOrder.setVisit_no(schedule.getVisit_no());

                    // 创建订单
                    order = orderService.createRegistrationOrder(newOrder);
                    paymentBean.setOrder_id(order.getOrder_id().intValue());
                } else {
                    // 如果提供了订单ID，验证订单是否存在
                    OrderBean existingOrder = orderService.getOrderById(paymentBean.getOrder_id());
                    if (existingOrder == null) {
                        return jsonResponse.fail("指定的订单不存在");
                    }
                    order = existingOrder;
                }

                // 设置支付记录默认值
                if (paymentBean.getPay_no() == null || paymentBean.getPay_no().isEmpty()) {
                    paymentBean.setPay_no("PAY" + System.currentTimeMillis());
                }
                if (paymentBean.getStatus() == null) {
                    paymentBean.setStatus(0); // 默认待支付状态
                }

                // 插入支付记录
                int row = paymentService.insertPaymentRecord(paymentBean);
                if (row > 0) {
                    // 返回订单和支付信息
                    Map<String, Object> data = new HashMap<>();
                    data.put("order", order);
                    data.put("payment", paymentBean);
                    return jsonResponse.success(data, "创建订单和支付记录成功");
                } else {
                    return jsonResponse.fail("支付记录创建失败");
                }
            } catch (Exception e) {
                e.printStackTrace();
                return jsonResponse.fail("系统错误: " + e.getMessage());
            }
        }

        /** 4. 标记已支付,将支付状态设置为1 */
        @PutMapping("/markPaid/{record_id}")
        @Transactional
        @OperateLog("标记已支付")
        public JsonResponse markPaid(@PathVariable Integer record_id) {
            JsonResponse resp = new JsonResponse();
            try {
                int row = paymentService.updatePaymentItemStatus(record_id);
                if (row > 0) {
                    resp.setCode(0);
                    resp.setMsg("标记成功");
                    resp.setData(row);
                } else {
                    resp.setCode(1);
                    resp.setMsg("标记失败");
                }
            } catch (Exception e) {
                resp.setCode(1);
                resp.setMsg("标记失败：" + e.getMessage());
            }
            return resp;
        }

     /** 5. 根据订单ID获取待支付项目 */
        @GetMapping("/pendingByOrder/{orderId}")
        @OperateLog("根据订单ID获取待支付项目")
        public JsonResponse pendingByOrder(@PathVariable Integer orderId) {
            JsonResponse resp = new JsonResponse();
            try {
                List<PaymentBean> list = paymentService.selectPendingItemsByOrderId(orderId);
                resp.setCode(0);
                resp.setMsg("查询成功");
                resp.setData(list);
            } catch (Exception e) {
                resp.setCode(1);
                resp.setMsg("查询失败：" + e.getMessage());
            }
            return resp;
        }

        /** 6. 根据交易号查询支付记录 */
        @GetMapping("/trade/{tradeNo}")
        @OperateLog("根据交易号查询支付记录")
        public JsonResponse trade(@PathVariable String tradeNo) {
            JsonResponse resp = new JsonResponse();
            try {
                PaymentBean bean = paymentService.selectPaymentByTradeNo(tradeNo);
                if (bean != null) {
                    resp.setCode(0);
                    resp.setMsg("查询成功");
                    resp.setData(bean);
                } else {
                    resp.setCode(1);
                    resp.setMsg("记录不存在");
                }
            } catch (Exception e) {
                resp.setCode(1);
                resp.setMsg("查询失败：" + e.getMessage());
            }
            return resp;
        }

        /** 7. 申请退款 */
        @PostMapping("/refund")
        @OperateLog("申请退款")
        public JsonResponse refund(@RequestBody PaymentBean paymentBean) {
            JsonResponse resp = new JsonResponse();
            try {
                int row = paymentService.applyRefund(paymentBean);
                if (row > 0) {
                    resp.setCode(0);
                    resp.setMsg("申请成功");
                    resp.setData(row);
                } else {
                    resp.setCode(1);
                    resp.setMsg("申请失败");
                }
            } catch (Exception e) {
                resp.setCode(1);
                resp.setMsg("申请失败：" + e.getMessage());
            }
            return resp;
        }

        /** 8. 支付结果通知 */
        @PostMapping("/notify")
        @OperateLog("支付结果通知")
        public JsonResponse notify(@RequestBody PaymentBean paymentBean) {
            JsonResponse resp = new JsonResponse();
            try {
                boolean ok = paymentService.processPaymentNotify(paymentBean);
                if (ok) {
                    resp.setCode(0);
                    resp.setMsg("处理成功");
                    resp.setData(true);
                } else {
                    resp.setCode(1);
                    resp.setMsg("处理失败");
                }
            } catch (Exception e) {
                resp.setCode(1);
                resp.setMsg("处理失败：" + e.getMessage());
            }
            return resp;
        }

        /** 9. 手动取消超时订单（用于测试或手动触发） */
        @PostMapping("/cancelTimeout")
        @OperateLog("取消超时订单")
        public JsonResponse cancelTimeout(int timeoutMinutes) {
            JsonResponse resp = new JsonResponse();
            try {
                int count = paymentService.cancelTimeoutPendingPayments(timeoutMinutes);
                resp.setCode(0);
                resp.setMsg("操作成功");
                resp.setData(count);
            } catch (Exception e) {
                resp.setCode(1);
                resp.setMsg("操作失败：" + e.getMessage());
            }
            return resp;
        }

}